package nborm;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Parcel;

import org.jetbrains.annotations.Nullable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;


class Query<T> implements Serializable, IQuery<T> {
    private Class<T> tClass;
    private SQLiteDatabase mLiteDatabase = DBHelper.get().getDb();
    private TableInfo mTableInfo;
    private String[] columns;
    private String selection;
    private String[] selectionArgs;
    private String groupBy;
    private String having;
    private String orderBy;
    private String limit;

    public Query(Class<T> tClass) {
        this.tClass = tClass;
        mTableInfo = TableHelper.getTableInfo(tClass);
    }

    public Query(Class<T> tClass, @Nullable String[] columns, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String groupBy, @Nullable String having, @Nullable String orderBy, @Nullable String limit) {
        this.columns = columns;
        this.selection = selection;
        this.selectionArgs = selectionArgs;
        this.groupBy = groupBy;
        this.having = having;
        this.orderBy = orderBy;
        this.limit = limit;
        this.tClass = tClass;
        mTableInfo = TableHelper.getTableInfo(tClass);
    }

    public String[] getColumns() {
        return columns;
    }

    public void setColumns(String[] columns) {
        this.columns = columns;
    }

    public String getSelection() {
        return selection;
    }

    public void setSelection(String selection) {
        this.selection = selection;
    }

    public String[] getSelectionArgs() {
        return selectionArgs;
    }

    public void setSelectionArgs(String[] selectionArgs) {
        this.selectionArgs = selectionArgs;
    }

    public String getGroupBy() {
        return groupBy;
    }

    public void setGroupBy(String groupBy) {
        this.groupBy = groupBy;
    }

    public String getHaving() {
        return having;
    }

    public void setHaving(String having) {
        this.having = having;
    }

    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }

    public String getLimit() {
        return limit;
    }

    public void setLimit(String limit) {
        this.limit = limit;
    }

    @Override
    public final List<T> list() {
        ArrayList<T> ts = new ArrayList<>();
        try {
            Cursor cursor = mLiteDatabase.query(mTableInfo.getTableName(), columns, selection, selectionArgs, groupBy, having, orderBy, limit);
            int count = cursor.getCount();
            if (cursor.moveToFirst()) {
                for (int i = 0; i < count; i++) {
                    T obj = QueryUtils.toObj(cursor, this.mTableInfo, tClass);
                    if (obj != null) {
                        ts.add(obj);
                    }
                    cursor.moveToNext();
                }
            }
            cursor.close();
        } catch (Exception ignored) {
        }
        return ts;
    }

    @Override
    @Nullable
    public final T unique() {
        List<T> result = this.list();
        return !result.isEmpty() ? result.get(0) : null;
    }

}
